/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.game.math.view.domain;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;
import org.game.math.config.Configure;
import org.game.math.expression.GenerateExpression;
import org.game.math.expression.Operator;

/**
 *
 * @author nmduc
 */
public class Examination extends Observable implements Observer {

    private List<MathExpression> expressionList;
    private static Examination examination;

    public List<MathExpression> getExpressionList() {
        return expressionList;
    }

    private Examination() {
        this.expressionList = new ArrayList<MathExpression>();
        Configure configure = Configure.getInstance();
        configure.addObserver(this);
        createExpression(configure);
    }

    public static Examination getInstance() {
        if (examination == null) {
            examination = new Examination();
        }
        return examination;
    }

    @Override
    public void update(Observable o, Object o1) {
        this.createExpression((Configure) o);
    }

    public void reset() {
        Configure configure = Configure.getInstance();
        this.createExpression(Configure.getInstance());
    }

    private void createExpression(Configure configure) {
        if (configure.isChosenMultiTable()) {
            this.createMultiplyTable(configure.getChosenMultiNumber());
        } else {
            String sign = configure.getProperty(Configure.SIGN);
            String numExpression = configure.getProperty(Configure.NUM_EXPRESSION);
            String numLength = configure.getProperty(Configure.NUM_LENGTH);
            String numOperator = configure.getProperty(Configure.NUM_OPERATOR);
            Set<Operator> operatorSet = configure.getOperators();
            this.expressionList.clear();
            this.expressionList.addAll(GenerateExpression.getInstance().generateExpression(
                    Integer.parseInt(numExpression), operatorSet, Integer.parseInt(numOperator),
                    Boolean.parseBoolean(sign), Integer.parseInt(numLength)));
            this.setChanged();
            this.notifyObservers();
        }
    }

    private void createMultiplyTable(int multipliedNumber) {
        this.expressionList.clear();
        this.expressionList.addAll(GenerateExpression.getInstance().generateMultiplyTable(multipliedNumber));
        this.setChanged();
        this.notifyObservers();
    }

    public long calculatePointsAndStopEditing() {
        int corrects = 0;
        for (MathExpression expresion : expressionList) {
            expresion.setCorrected(expresion.getInputResult().trim().equalsIgnoreCase(expresion.getResult()));
            if (expresion.isCorrected()) {
                corrects++;
            }
        }
        long points = Math.round(corrects * 10.0 / expressionList.size());
        this.setChanged();
        this.notifyObservers();
        return points;
    }
}
